#include<jni.h>
#include <stdlib.h>

jboolean checkUtfBytes(const char* bytes, const char** errorKind) ;

jstring Java_com_example_gch_hellocmakejnidemo_MainActivity_getCiphertext
        (JNIEnv *env, jobject object, jstring data){
    if(data==NULL){
        return (*env)->NewStringUTF(env, "");
    }
    jsize len = (*env)->GetStringLength(env, data);
    char *buffer = (char *) malloc(len * sizeof(char));
    (*env)->GetStringUTFRegion(env, data, 0, len, buffer);
    int i=0;
    for (; i <len ; i++) {
        buffer[i] = (char) (buffer[i] ^ 2);
    }

    const char *errorKind = NULL;
    checkUtfBytes(buffer, &errorKind);
    free(buffer);
    if (errorKind == NULL) {
        return (*env)->NewStringUTF(env, buffer);
    } else {
        return (*env)->NewStringUTF(env, "");
    }
}

//把char*和errorKind传入,如果errorKind不为NULL说明含有非utf-8字符,做相应处理
jboolean checkUtfBytes(const char* bytes, const char** errorKind) {
    while (*bytes != '\0') {
        jboolean utf8 = *(bytes++);
        // Switch on the high four bits.
        switch (utf8 >> 4) {
            case 0x00:
            case 0x01:
            case 0x02:
            case 0x03:
            case 0x04:
            case 0x05:
            case 0x06:
            case 0x07:
                // Bit pattern 0xxx. No need for any extra bytes.
                break;
            case 0x08:
            case 0x09:
            case 0x0a:
            case 0x0b:
            case 0x0f:
                /*
                 * Bit pattern 10xx or 1111, which are illegal start bytes.
                 * Note: 1111 is valid for normal UTF-8, but not the
                 * modified UTF-8 used here.
                 */
                *errorKind = "start";
                return utf8;
            case 0x0e:
                // Bit pattern 1110, so there are two additional bytes.
                utf8 = *(bytes++);
                if ((utf8 & 0xc0) != 0x80) {
                    *errorKind = "continuation";
                    return utf8;
                }
                // Fall through to take care of the final byte.
            case 0x0c:
            case 0x0d:
                // Bit pattern 110x, so there is one additional byte.
                utf8 = *(bytes++);
                if ((utf8 & 0xc0) != 0x80) {
                    *errorKind = "continuation";
                    return utf8;
                }
                break;
        }
    }
    return 0;
}
